﻿using AesonBaseFramework.EntityFramework.BaseEntities;
using AesonIntegrationTestLibrary.PubSubEvents;
using Microsoft.Practices.Prism.PubSubEvents;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;

namespace AesonIntegrationTestLibrary.DataModel
{
    public class AesonTest : AesonBaseEntity
    {
        #region Private Fields

        private static IEventAggregator ea;

        private string _curentProcess;
        private TimeSpan _duration;

        private DateTime _endDate;

        private List<TestEvent> _events;

        private string _message;

        private int _messageCount;
        private string _method;

        private string _stackTrace;

        private DateTime _startDate;

        private TestStatut _statut;

        private Guid _testID;

        #endregion Private Fields

        #region Public Properties

        public string CurentProcess
        {
            get { return _curentProcess; }
            set
            {
                if (value == _curentProcess) return;
                _curentProcess = value;
                OnPropertyChanged();
            }
        }

        public TimeSpan Duration
        {
            get { return _duration; }
            set
            {
                if (value == _duration) return;
                _duration = value;
                OnPropertyChanged();
            }
        }

        public DateTime EndDate
        {
            get { return _endDate; }
            set
            {
                if (value == _endDate) return;
                _endDate = value;
                OnPropertyChanged();
            }
        }

        public List<TestEvent> Events
        {
            get { return _events; }
            set
            {
                if (value == _events) return;
                _events = value;
                OnPropertyChanged();
            }
        }

        public string Message
        {
            get { return _message; }
            set
            {
                if (value == _message) return;
                _message = value;
                OnPropertyChanged();
            }
        }

        public int MessageCount
        {
            get { return _messageCount; }
            set
            {
                if (value == _messageCount) return;
                _messageCount = value;
                OnPropertyChanged();
            }
        }

        public string Method
        {
            get { return _method; }
            set
            {
                if (value == _method) return;
                _method = value;
                OnPropertyChanged();
            }
        }

        public string StackTrace
        {
            get { return _stackTrace; }
            set
            {
                if (value == _stackTrace) return;
                _stackTrace = value;
                OnPropertyChanged();
            }
        }

        public DateTime StartDate
        {
            get { return _startDate; }
            set
            {
                if (value == _startDate) return;
                _startDate = value;
                OnPropertyChanged();
            }
        }

        public TestStatut Statut
        {
            get { return _statut; }
            set
            {
                if (value == _statut) return;
                _statut = value;
                OnPropertyChanged();
            }
        }

        public Guid TestID
        {
            get { return _testID; }
            set
            {
                if (value == _testID) return;
                _testID = value;
                OnPropertyChanged();
            }
        }

        #endregion Public Properties

        #region Internal Methods

        internal static AesonTest Create(IEventAggregator eav, [CallerMemberName]string methode = "")
        {
            ea = eav;
            var t = new AesonTest
            {
                TestID = Guid.NewGuid(),
                Statut = TestStatut.Created,
                Method = methode,
                StartDate = DateTime.Now,
                Events = new List<TestEvent>()
            };
            ea.GetEvent<AesonTestCreatedEvent>().Publish(t);
            return t;
        }

        internal void AddEvent(string m)
        {
            TestEvent t = TestEvent.Create(m, TestID);
            this.Events.Add(t);
            this.CurentProcess = m;
            this.MessageCount++;
            ea.GetEvent<EventAddedToTestEvent>().Publish(t);
        }

        internal void EndTest(TestStatut result, string message)
        {
            this.Statut = result;
            this.Message = message;
            this.EndDate = DateTime.Now;
            this.Duration = EndDate.Subtract(StartDate);
            this.CurentProcess = null;
            ea.GetEvent<AesonTestEndedEvent>().Publish(this);
        }

        #endregion Internal Methods
    }
}